<template>
  <el-card style="height: 80px; margin: 20px 0px">
    <el-form :inline="true" class="form">
      <el-form-item label="角色名称">
        <el-input placeholder="请输入角色关键词" v-model="keyword"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="search">搜索</el-button>
        <el-button @click="reset">重置</el-button>
      </el-form-item>
    </el-form>
  </el-card>
  <el-card>
    <el-form>
      <el-form-item>
        <el-button type="primary" @click="addRole">添加角色</el-button>
      </el-form-item>
      <el-form-item style="margin: 20px 0px">
        <el-table border :data="RoleInfo">
          <el-table-column
            label="#"
            type="index"
            align="center"
            width="80px"
          ></el-table-column>
          <el-table-column
            label="ID"
            align="center"
            prop="id"
          ></el-table-column>
          <el-table-column
            label="角色名称"
            align="center"
            prop="roleName"
          ></el-table-column>
          <el-table-column
            label="创建时间"
            align="center"
            prop="createTime"
          ></el-table-column>
          <el-table-column
            label="更新时间"
            align="center"
            prop="updateTime"
          ></el-table-column>
          <el-table-column
            label="操作"
            align="center"
            width="350px"
            fixed="right"
          >
            <template #="{ row }">
              <el-button type="primary" icon="User" @click="setPermission(row)"
                >分配权限</el-button
              >
              <el-button type="warning" icon="Edit" @click="update(row)"
                >编辑</el-button
              >
              <el-popconfirm
                :title="`你确定要删除${row.roleName}?`"
                @confirm="deleteRole(row)"
                width="200px"
              >
                <template #reference>
                  <el-button type="danger" icon="Delete">删除</el-button>
                </template>
              </el-popconfirm>
            </template>
          </el-table-column>
        </el-table>
      </el-form-item>
      <el-form-item>
        <el-pagination
          v-model:current-page="pageNo"
          v-model:page-size="limit"
          :page-sizes="[3, 5, 7, 9]"
          size="large"
          :background="true"
          layout="total,prev, pager, next, jumper, -> , sizes, total"
          :total="total"
          @current-change="getRoleInfo"
          @size-change="handler"
        />
      </el-form-item>
    </el-form>
  </el-card>
  <el-dialog
    v-model="dialogVisible"
    :title="roleParams.id ? '更新角色' : '添加角色'"
    width="500"
  >
    <el-form :model="roleParams" :rules="rules" ref="useFormRef">
      <el-form-item label="角色名称" style="width: 250px" prop="roleName">
        <el-input v-model="roleParams.roleName"></el-input>
      </el-form-item>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="save"> 确认 </el-button>
      </div>
    </template>
  </el-dialog>
  <el-drawer v-model="drawer">
    <template #header>
      <h4>分配菜单和按钮的权限</h4>
    </template>
    <template #default>
      <!--树形控件-->
      <el-tree
        style="max-width: 600px"
        :data="permissionArr"
        show-checkbox
        node-key="id"
        default-expand-all
        :default-checked-keys="selectedIdArr"
        :props="defaultProps"
        ref="useTreeRef"
      />
    </template>
    <template #footer>
      <div style="flex: auto">
        <el-button @click="cancelClick">取消</el-button>
        <el-button type="primary" @click="savePermisson">确认</el-button>
      </div>
    </template>
  </el-drawer>
</template>

<script setup lang="ts">
  import {
    reqAddOrUpdateRole,
    reqDeleteRole,
    reqPermissionList,
    reqRoleInfoByPage,
    reqSetPermission,
  } from '@/api/acl/role'
  import { ref, onMounted, reactive, nextTick } from 'vue'
  import type { RoleData } from '@/api/acl/user/type'
  import { ElMessage } from 'element-plus'
  import useLayoutSettingStore from '@/store/modules/layoutSetting'
  import type { PermissionList } from '@/api/acl/role/type'

  let total = ref<number>(100)
  let pageNo = ref<number>(1)
  let limit = ref<number>(3)
  let RoleInfo = ref<RoleData[]>([])
  let keyword = ref<string>('')
  let settingStore = useLayoutSettingStore() //获取页面配置相关的小仓库
  let dialogVisible = ref<boolean>(false)
  let roleParams = reactive<{ roleName: string; id?: number }>({
    roleName: '',
    id: 0,
  })
  let useFormRef = ref() //添加角色表单实例
  let drawer = ref<boolean>(false) //控制分配权限抽屉的显示与隐藏
  let permissionArr = ref<PermissionList>([]) //存储获取到的权限列表
  let selectedIdArr = ref<number[]>([]) //存储已被分配的权限id数组
  let useTreeRef = ref() //树形控件实例

  onMounted(() => {
    getRoleInfo()
  })

  const getRoleInfo = async (pager = 1) => {
    pageNo.value = pager
    let result = await reqRoleInfoByPage(
      pageNo.value,
      limit.value,
      keyword.value,
    )
    if (result.code === 200) {
      RoleInfo.value = result.data.records
      total.value = result.data.total
    } else {
      ElMessage({ type: 'error', message: '获取角色信息失败，请刷新页面重试' })
    }
  }
  //每页最大显示数变化时的回调
  const handler = () => {
    getRoleInfo()
  }

  const search = () => {
    getRoleInfo()
    keyword.value = ''
  }
  const reset = () => {
    settingStore.refresh = !settingStore.refresh
  }
  //点击添加按钮时的回调
  const addRole = () => {
    //清除已有数据
    Object.assign(roleParams, {
      roleName: '',
      id: 0,
    })
    dialogVisible.value = true
    //清除校验信息
    nextTick(() => {
      useFormRef.value.clearValidate()
    })
  }
  const validateRoleName = (rule: any, value: any, callback: any) => {
    if (value.trim().length < 2) {
      callback(new Error('角色名的长度不能少于2位'))
    } else {
      callback()
    }
  }
  //添加功能表单校验对象
  const rules = {
    roleName: [
      { required: true, trigger: 'blur', validator: validateRoleName },
    ],
  }
  const save = async () => {
    await useFormRef.value.validate()
    let result = await reqAddOrUpdateRole(roleParams)
    if (result.code === 200) {
      ElMessage({
        type: 'success',
        message: roleParams.id ? '角色更新成功' : '角色添加成功',
      })
      getRoleInfo(roleParams.id ? pageNo.value : 1)
      dialogVisible.value = false
    } else {
      ElMessage({
        type: 'error',
        message: roleParams.id ? '角色更新失败' : '角色添加失败',
      })
    }
  }

  const update = (row: RoleData) => {
    Object.assign(roleParams, row)
    dialogVisible.value = true
  }

  //树控件提供的API
  const defaultProps = {
    children: 'children',
    label: 'name',
  }

  const setPermission = async (row: RoleData) => {
    Object.assign(roleParams, row)
    let result = await reqPermissionList(row.id)
    if (result.code === 200) {
      permissionArr.value = result.data
      selectedIdArr.value = filterSelectedId(permissionArr.value, [])
      drawer.value = true
    } else {
      ElMessage({ type: 'success', message: '无法获取到权限信息，请重试' })
    }
  }
  //过滤已分配权限的id为数组
  const filterSelectedId = (data: any, initArr: any) => {
    data.forEach((item: any) => {
      if (item.select === true) {
        initArr.push(item.id)
      }
      if (item.children && item.children.length > 0) {
        filterSelectedId(item.children, initArr)
      }
    })
    return initArr
  }

  //分配权限抽屉的确认按钮的事件回调
  const savePermisson = async () => {
    //选择项对应的id
    let arr = useTreeRef.value.getCheckedKeys()
    let arr1 = useTreeRef.value.getHalfCheckedKeys() //
    let result = await reqSetPermission(roleParams.id as number, [
      ...arr,
      ...arr1,
    ])
    if (result.code === 200) {
      ElMessage({ type: 'success', message: '分配权限成功' })
      getRoleInfo(pageNo.value)
      drawer.value = false
    } else {
      ElMessage({ type: 'error', message: '分配权限失败' })
    }
  }

  const cancelClick = () => {
    drawer.value = false
  }

  const deleteRole = async (row: RoleData) => {
    let result = await reqDeleteRole(row.id)
    if (result.code === 200) {
      ElMessage({ type: 'success', message: '删除角色成功' })
      getRoleInfo(RoleInfo.value.length > 1 ? pageNo.value : pageNo.value - 1)
    } else {
      ElMessage({ type: 'error', message: '删除角色失败' })
    }
  }
</script>

<style scoped>
  .form {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
</style>
